package com.rp.security.extend;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import com.rp.system.dao.AuthorityDao;
import com.rp.system.dao.ResourceDao;
import com.rp.system.po.Authority;
import com.rp.system.po.Resource;

@Service
public class MySecurityMetadataSource implements
		FilterInvocationSecurityMetadataSource {
	
	private static Logger log = Logger.getLogger(MySecurityMetadataSource.class);
	
	@Autowired
	private ResourceDao resourceDao;
	@Autowired
	private AuthorityDao authorityDao;
	
	/* 保存资源和权限的对应关系  key-资源url  value-权限 */  
    private Map<String,Collection<ConfigAttribute>> resourceMap = null;
	private PathMatcher urlMatcher = new AntPathMatcher();
	
	public void init() throws Exception {
		this.loadResourcesDefine();
	}
	
	public void loadResourcesDefine(){
		resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>();
		List<Resource> rescs = resourceDao.getAllResources();
		for (Resource resc : rescs) {
			resourceMap.put(resc.getUrl(), 
					listToCollection(authorityDao.getAuthoritiesByResourceId(resc.getId())));
		}
		log.info("resourceMapSize="+resourceMap.size());
	}

	/**
	 * 根据请求的资源地址，获取它所拥有的权限   
	 */
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		//获取当前访问的URL地址
		String url = ((FilterInvocation) object).getRequestUrl();
		//String method = ((FilterInvocation) object).getHttpRequest().getMethod();
		
        Iterator<String> it = resourceMap.keySet().iterator();
        while(it.hasNext()){  
            String _url = it.next();  
            if(_url.indexOf("?") != -1){  
                _url = _url.substring(0, _url.indexOf("?"));  
            }  
            if(urlMatcher.match(_url, url))  
                return resourceMap.get(_url);
        }  
        //没有匹配上，则返回null
        return null;  
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
		for (Map.Entry<String, Collection<ConfigAttribute>> entry : resourceMap
				.entrySet()) {
			allAttributes.addAll(entry.getValue());
		}
		return allAttributes;
	}

	public boolean supports(Class<?> clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}
	
	
	private Collection<ConfigAttribute> listToCollection(Collection<Authority> authorities) {
		List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
		for (Authority authority : authorities) {
			list.add(new SecurityConfig(authority.getCode()));
		}
		return list;
	}
	
	
}
